{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "48974b41-9328-4aa9-b38d-8dead238d67c",
   "metadata": {},
   "source": [
    "Chapter 17\n",
    "\n",
    "# 正交回归，多元\n",
    "Book_7《机器学习》 | 鸢尾花书：从加减乘除到机器学习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5f63fc2e-44b7-4d8a-9172-ebd3b48d1093",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import yfinance as yf\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import scipy.stats as stats"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8fc56819-abf8-476a-9695-e9d352e91cbe",
   "metadata": {},
   "outputs": [],
   "source": [
    "p = plt.rcParams\n",
    "p[\"font.sans-serif\"] = [\"Roboto\"]\n",
    "p[\"font.weight\"] = \"light\"\n",
    "p[\"ytick.minor.visible\"] = True\n",
    "p[\"xtick.minor.visible\"] = True\n",
    "p[\"axes.grid\"] = True\n",
    "p[\"grid.color\"] = \"0.5\"\n",
    "p[\"grid.linewidth\"] = 0.5\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c609cd51-468e-491f-9e7b-7c88d23cd61a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[*********************100%%**********************]  13 of 13 completed\n"
     ]
    }
   ],
   "source": [
    "tickers = ['TSLA','WMT','MCD','USB',\n",
    "           'YUM','NFLX','JPM','PFE',\n",
    "           'F','GM','COST','JNJ', '^GSPC'];\n",
    "\n",
    "stock_levels_df = yf.download(tickers, start='2020-01-01', end='2020-12-31')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "3171a442-61a4-485d-9fc2-203baab01e45",
   "metadata": {},
   "outputs": [],
   "source": [
    "stock_levels_df.to_csv('stock_levels_df.csv')\n",
    "stock_levels_df.to_pickle('stock_levels_df.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "486cf58a-e41f-4034-81bc-35043ecc99c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_y_df = stock_levels_df['Adj Close'].pct_change()\n",
    "X_y_df.dropna(inplace = True)\n",
    "\n",
    "X_y_df.rename(columns={\"^GSPC\": \"SP500\"},inplace = True)\n",
    "X_df = X_y_df.iloc[:,:-1]\n",
    "y_df = X_y_df[['SP500']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "91f4574e-7167-41f5-b2df-74e211ac9c79",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.25908786  0.01824322  0.0373678   0.25978646  0.15377967  0.17647761\n",
      "  0.11275032  0.04741226  0.02438509  0.04140727 -0.03435162  0.01765148]\n"
     ]
    }
   ],
   "source": [
    "#%% TLS, matrix computation\n",
    "\n",
    "SIMGA = X_y_df.cov()\n",
    "\n",
    "Lambda, V = np.linalg.eig(SIMGA)\n",
    "\n",
    "idx = Lambda.argsort()[::-1]   \n",
    "Lambda = Lambda[idx]\n",
    "V = V[:,idx]\n",
    "\n",
    "lambda_min = np.min(Lambda)\n",
    "\n",
    "D = len(tickers[:-1])\n",
    "\n",
    "b_TLS_ = -V[0:D,D]/V[D,D]\n",
    "\n",
    "print(b_TLS_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b9c538b5-2643-462c-a85f-bb6eed55ed7c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.00039445]\n"
     ]
    }
   ],
   "source": [
    "b0_TLS_ = y_df.mean().values - b_TLS_@X_df.mean().values\n",
    "print(b0_TLS_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "444d5d07-2649-40ca-a940-ee0bcd062bbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "b_TLS = np.hstack((b0_TLS_,b_TLS_))\n",
    "\n",
    "labels = ['const'] + tickers[:-1]\n",
    "b_df_TLS = pd.DataFrame(data=b_TLS.T, index=[labels], columns=['TLS']) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "354bd1c4-6a82-4a6a-8019-f624ff530929",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                            OLS Regression Results                            \n",
      "==============================================================================\n",
      "Dep. Variable:                  SP500   R-squared:                       0.938\n",
      "Model:                            OLS   Adj. R-squared:                  0.935\n",
      "Method:                 Least Squares   F-statistic:                     301.8\n",
      "Date:                Tue, 21 Nov 2023   Prob (F-statistic):          1.71e-136\n",
      "Time:                        20:18:41   Log-Likelihood:                 954.64\n",
      "No. Observations:                 251   AIC:                            -1883.\n",
      "Df Residuals:                     238   BIC:                            -1837.\n",
      "Df Model:                          12                                         \n",
      "Covariance Type:            nonrobust                                         \n",
      "==============================================================================\n",
      "                 coef    std err          t      P>|t|      [0.025      0.975]\n",
      "------------------------------------------------------------------------------\n",
      "const         -0.0004      0.000     -1.111      0.267      -0.001       0.000\n",
      "COST           0.2135      0.034      6.274      0.000       0.146       0.280\n",
      "F              0.0173      0.019      0.912      0.363      -0.020       0.055\n",
      "GM             0.0425      0.018      2.405      0.017       0.008       0.077\n",
      "JNJ            0.2199      0.033      6.641      0.000       0.155       0.285\n",
      "JPM            0.1332      0.029      4.528      0.000       0.075       0.191\n",
      "MCD            0.1577      0.028      5.650      0.000       0.103       0.213\n",
      "NFLX           0.1137      0.016      7.273      0.000       0.083       0.145\n",
      "PFE            0.0665      0.024      2.801      0.006       0.020       0.113\n",
      "TSLA           0.0266      0.008      3.456      0.001       0.011       0.042\n",
      "USB            0.0583      0.025      2.353      0.019       0.009       0.107\n",
      "WMT            0.0132      0.029      0.459      0.647      -0.043       0.070\n",
      "YUM            0.0404      0.024      1.680      0.094      -0.007       0.088\n",
      "==============================================================================\n",
      "Omnibus:                       31.960   Durbin-Watson:                   2.128\n",
      "Prob(Omnibus):                  0.000   Jarque-Bera (JB):               70.936\n",
      "Skew:                           0.617   Prob(JB):                     3.95e-16\n",
      "Kurtosis:                       5.294   Cond. No.                         114.\n",
      "==============================================================================\n",
      "\n",
      "Notes:\n",
      "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n"
     ]
    }
   ],
   "source": [
    "#%% OLS Regression\n",
    "import statsmodels.api as sm\n",
    "\n",
    "# add a column of ones\n",
    "X_df = sm.add_constant(X_df)\n",
    "\n",
    "model = sm.OLS(y_df, X_df)\n",
    "results = model.fit()\n",
    "print(results.summary())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5465e943-64ee-4576-817a-23bfc6d47234",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "const   -0.000396\n",
      "COST     0.213459\n",
      "F        0.017301\n",
      "GM       0.042511\n",
      "JNJ      0.219896\n",
      "JPM      0.133239\n",
      "MCD      0.157656\n",
      "NFLX     0.113743\n",
      "PFE      0.066497\n",
      "TSLA     0.026612\n",
      "USB      0.058301\n",
      "WMT      0.013201\n",
      "YUM      0.040400\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "b_df_OLS = model.fit().params\n",
    "print(b_df_OLS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ea34df84-10c9-4624-ac56-411cc7a9322d",
   "metadata": {},
   "outputs": [],
   "source": [
    "b_df_OLS = pd.DataFrame(data=b_df_OLS.values, index=[labels], columns=['OLS']) \n",
    "\n",
    "\n",
    "coeffs = pd.concat([b_df_TLS, b_df_OLS], axis=1, join=\"inner\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2e4ec2e9-036e-4745-96b0-da7189420e71",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>TLS</th>\n",
       "      <th>OLS</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>const</th>\n",
       "      <td>-0.000394</td>\n",
       "      <td>-0.000396</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>TSLA</th>\n",
       "      <td>0.259088</td>\n",
       "      <td>0.213459</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>WMT</th>\n",
       "      <td>0.018243</td>\n",
       "      <td>0.017301</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MCD</th>\n",
       "      <td>0.037368</td>\n",
       "      <td>0.042511</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>USB</th>\n",
       "      <td>0.259786</td>\n",
       "      <td>0.219896</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>YUM</th>\n",
       "      <td>0.153780</td>\n",
       "      <td>0.133239</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NFLX</th>\n",
       "      <td>0.176478</td>\n",
       "      <td>0.157656</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JPM</th>\n",
       "      <td>0.112750</td>\n",
       "      <td>0.113743</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>PFE</th>\n",
       "      <td>0.047412</td>\n",
       "      <td>0.066497</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>F</th>\n",
       "      <td>0.024385</td>\n",
       "      <td>0.026612</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GM</th>\n",
       "      <td>0.041407</td>\n",
       "      <td>0.058301</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>COST</th>\n",
       "      <td>-0.034352</td>\n",
       "      <td>0.013201</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>JNJ</th>\n",
       "      <td>0.017651</td>\n",
       "      <td>0.040400</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            TLS       OLS\n",
       "const -0.000394 -0.000396\n",
       "TSLA   0.259088  0.213459\n",
       "WMT    0.018243  0.017301\n",
       "MCD    0.037368  0.042511\n",
       "USB    0.259786  0.219896\n",
       "YUM    0.153780  0.133239\n",
       "NFLX   0.176478  0.157656\n",
       "JPM    0.112750  0.113743\n",
       "PFE    0.047412  0.066497\n",
       "F      0.024385  0.026612\n",
       "GM     0.041407  0.058301\n",
       "COST  -0.034352  0.013201\n",
       "JNJ    0.017651  0.040400"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coeffs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "08b5e241-1e53-4fe8-a60a-15be9000c4ab",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.lines.Line2D at 0x1b0e2a30790>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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2qG7SE77fJ32d85p+zTDMIwVK1YY+/fvN/26t956q132Ex3qiN3GjRs1evRo06/7+9//rsbGRuXn5yehq9hqamrUpUuXs3ptbW2tOnfu3MYdwWrl5eVn9c26sbFRR48ebfehl+3bt6uwsND062pra1VdXW27YRecu7fffltjxowxfbulTz75RPn5+e2+H3Yap/2dc9o+zQk6VLAzY/369erVq5cuuugiW523FsvixYvl9Xr1k5/8xNIhITNO9ZyTk6Of//znVrfTKif2m56ertGjR6tfv35Wt9OqxYsXq1evXhozZowjvpQsXrw4dMrD9OnTLe4mMU7bhp3GaZ+vE//OOWmfJp3eJjwej6ZNm9Yu70mwi2H//v3y+Xz69ttvNXXqVKvbSdj//M//6Cc/+YnVbZhyLkcmreC0fjds2KArrrjC6jYSUlNTo3Xr1qmoqMjqVlzNKduwE8Oz5JzP16l/55y0TzvFMIx2C88EuxgaGhoccdPhQCCg1atX6/Dhw7r33nutbkeS9P7772vSpElWt3FWDh8+rP3796u+vl5ZWVkqKChQ7969rW4rYfX19WpqalKnTp2sbsWx/v3f/1333Xdf3KHCvXv36s0339Rvf/vb9msMlvnkk0901VVXWd2Ga23btk1Dhw61ug3X6NDTnSxZskQzZsyI+tzLL7+s++67r507SkxjY6NWr16trVu3qqCgQJMmTbLVeQYHDhywugXTNm3apE2bNmngwIG68MILlZmZqfr6em3ZskX79u3Tz372M11++eVWtxnyxhtv6OTJk2poaFBBQYEmTJig0tJS9ejRQ16vV4cOHdItt9yivn37Wt2qXnnlldD/n/oeeeY311PfZu+444527S2a4uJiLVy4UP3799dNN90U9lwwGNTLL7+s7t272yrU3XnnnRo7dmzoKsxon7OdPuNly5ZFDEsdP3484qr/aHVW2LlzZ0Swe+mll3T33Xdb1FF8n3zyScK1dgisGzdudFywW7x4ccwjcCkpKQoGgwoEApo5c2a7T+PUIYPdJ598IsMw9NVXX0Udp6+urlZ1dbUFncXW2Nio9957TwcPHlRmZqYmTZqkI0eO2GIn7XSff/65Kioq9Otf/zriuQsvvFCStHLlSkmyRbh7+eWX9fOf/1y9evWSJK1du1aPPfaY/uEf/kE9e/YM1T399NN6+OGHrWoz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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "coeffs.plot.bar(ax = ax)\n",
    "# h.legend(loc='center left', bbox_to_anchor=(1, 0.5))\n",
    "plt.tight_layout()\n",
    "plt.axhline(y=0, color='r', linestyle='--')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
